<script>
/*
 * @Author: Your name
 * @Date:   2020-07-03 23:27:19
 * @Last Modified by:   Your name
 * @Last Modified time: 2020-07-26 16:49:29
 */
</script>
<template>
    <div class="detail">
        <detail-nav-bar ref="detailnavbar" @typeClick = "typeClick"></detail-nav-bar>
        <scroll class="content2" ref = "scroll" :probeType="3" @scroll="getScrollY">
          <div>
            <detail-swiper ref="basic" :id = id @detailSwiperLoad = 'swiperIsLoad' :top-images="topImages"></detail-swiper>
            <detail-basic-info :id = "id" :goods-item="goodsItem"></detail-basic-info>
            <detail-shop-info :shop = "shopInfos"></detail-shop-info>
            <detail-images-info ref="params" :detail-images-info = "detailImages" @detaliImgLoad = "detailImageLoad"></detail-images-info>
            <detail-params-info :detail-params-info = "detailParams"></detail-params-info>
            <detail-comment ref="comment" :detail-comment = "commentMessage"></detail-comment>
            <goods-list ref="recommend" :goods = "recommendMessage"></goods-list>  <!-- 体现出了组件的复用性 -->
          </div> 
        </scroll>
        <detail-bottom-bar @addCart="addToCart"></detail-bottom-bar>
        <back-top @click.native="clickBackTop" v-show="isShow"></back-top>
    </div>
    
</template>
<script>
import DetailNavBar from './childComps/DetailNavBar.vue';
import DetailSwiper from './childComps/DetailSwiper.vue';
import DetailBasicInfo from './childComps/DetailBasicInfo.vue';
import DetailShopInfo from './childComps/DetailShopInfo.vue';
import DetailImagesInfo from './childComps/DetailImagesInfo.vue';
import DetailParamsInfo from './childComps/DetailParamsInfo.vue';
import DetailComment from './childComps/DetailComment.vue';
import GoodsList from '../../components/content/goods/GoodsList.vue';
import DetailBottomBar from './childComps/DetailBottomBar.vue';
import Scroll from '../../components/common/scoll/Scroll.vue';
import BackTop from '../../components/common/backtop/BackTop.vue';
import {getDetailMessage, getCommentMessage, getRecommendMessage, goodsInfos} from '../../network/detail.js';
import {debounce} from '../../common/utils.js';
import { Toast } from 'mint-ui';
export default {
    name:'Detail',
    data(){
        return {
            id: null,
            shopInfos: {},
            goodsItem: {},
            topImages: [],
            detailImages: [],
            detailParams: {},
            commentMessage: [],
            recommendMessage: [],
            itemImgListener: null,
            typeTopY: [],
            getTypeTopY: null,
            isShow: false
        }
    },
    methods: {
      typeClick(index){
        // console.log(index);
        this.$refs.scroll.scrollTo(0, -this.typeTopY[index]);
      },
      swiperIsLoad(){
        
        //这里没有对swiperIsLoad做什么处理
      },
      //这里监听一下子组件中detailImageInfo.vue中的图片加载完成事件，并添加防抖函数
      detailImageLoad(){
        this.getTypeTopY();
      },
      //根据获取滚动的位置显示标题
      getScrollY(position){
        /* 
          如果不给scroll组件的probeType值设置成非零，better-scroll组件是不会进行监听滚动值得
        */
       //[0, 620, 5598, 6166, big] 给数组最后加一个最大值可以简化if中的判断
        // console.log(-position.y);
        const scrollY = -position.y;
        //控制回到顶部的图标的显示和隐藏
        this.isShow = scrollY > 1000;
        for(let i = 0; i < this.typeTopY.length; i++){
          if(scrollY >= this.typeTopY[i] && scrollY < this.typeTopY[i+1]){
            this.$refs.detailnavbar.currentIndex = i;
          }
        }
      },
      //回到顶部
      clickBackTop(){
        this.$refs.scroll.scrollTo(0, 0, 500);
      },
      //点击添加购物车
      addToCart(){
        /* 
          先将购物车中需要显示的商品信息整理成一个对象，将这个对象添加到vuex中的store中去
        */
        let goodObj = {};
        goodObj.id = this.id;
        goodObj.goodsName = this.goodsItem.title;
        goodObj.newPrice = this.goodsItem.newPrice;
        goodObj.image = this.topImages[0];
        goodObj.count = 0;
        
        //发送actions
        /* 
          新知识：在这里我们也可以直接用this.addCart()的方式来调用，我们需要用到mapActions将他们映射为方法。
        */
        this.$store.dispatch('addCart', goodObj)
        .then(function(data){
          Toast({
            message: data,
            position: 'middle',
            duration: 5000
          });
        });
        /* 
          加入购物车成功，但是加入成功的操作我们不能在这里执行，应该在actions里面执行，等里面完成了操作，再显示
          添加成功，而不是按钮一点击就触发添加成功的提示。dispatch会返回一个promise,通过promise来监听是否完成。
        */
      }
    },
    created(){
        console.log(this.$route.params);
        this.id = this.$route.params.id;
        //其实所有的商品相关信息都应该在Deteil.vue文件中进行请求，再将数据传递给对应的子组件。这里暂时不做修改
        //....
        //获取商品的相关数据信息
        getDetailMessage(this.id)
        .then((res => {
          // console.log('店铺数据',res.message.shopInfos);
          this.shopInfos = res.message.shopInfos;
          //获取商品的详细图片信息
          this.detailImages = res.message.detailImages;
          //获取商品的参数信息(尺码等相关参数)
          this.detailParams = res.message.rules;
          //获取商品的基本参数（名字，价格等）
          this.goodsItem =
            new goodsInfos(res.message.title, res.message.newPrice, res.message.oldPrice, res.message.discount, res.message.sellCounts, res.message.store, res.message.service, res.message.promise); 
            console.log('goodsItem:',res.message);
          //获取详情页顶部的轮播图
          this.topImages = res.message.topImages;
        }))
        .catch(error => {
          console.log(error);
        });

        //获取商品的参数信息(尺码等相关参数)
        // getDetailMessage(this.id)
        // .then(res => {
        //   this.detailParams = res.message.rules;
        // })
        // .catch(error => {
        //   console.log(error)
        // });
        
        //获取商品评论信息
        getCommentMessage(this.id)
        .then(res => {
          // console.log(res.message.commentMes);
          this.commentMessage = res.message.commentMes;
        })
        .catch(error => {
          console.log(error);
        });

        //获取商品推荐信息
        getRecommendMessage()
        .then(res => {
          console.log(res.message);
          this.recommendMessage = res.message;
        })
        .catch(error => {
          console.log(error);
        });
        /* 
          在这里（created钩子）中直接连this.$nextTick()都不加，肯定是错误的压根dom没有渲染
          this.$nextTick(() => {
          this.typeTopY = [];
          this.typeTopY.push(0);
          this.typeTopY.push(this.$refs.params.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          this.typeTopY.push(this.$refs.comment.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          this.typeTopY.push(this.$refs.recommend.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          console.log('topYarr',this.typeTopY);
        */

        /* 
          在这里（created钩子）中通过this.$nextTick()来获取dom的offsetTop获得到的数据也不准确
          原因：因为图片还没有完全加载完，所以应该放在图片加载的监听事件函数中。
          this.$nextTick(() => {
          this.typeTopY = [];
          this.typeTopY.push(0);
          this.typeTopY.push(this.$refs.params.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          this.typeTopY.push(this.$refs.comment.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          this.typeTopY.push(this.$refs.recommend.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          console.log('topYarr',this.typeTopY);
        })
        */
        //获取dom的offsetTop的方法，应该在图片加载事件监听中调用
        this.getTypeTopY = debounce(() => {
          console.log('deltaiImage加载了');
          /* 
            点击tabControl滚动到相应位置,获取每个部分的offsettop值
            获取值的地方有讲究：要考虑必须在数据全部请求到以后，并且dom渲染完毕，图片全部加载完成以后
            this.$nextTick(()=>{});下一帧,通过它我们可以在created()钩子中获得dom，就像一个定时器异步的去获取dom
          */
          this.typeTopY = [];
          this.typeTopY.push(0);
          this.typeTopY.push(this.$refs.params.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          this.typeTopY.push(this.$refs.comment.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          this.typeTopY.push(this.$refs.recommend.$el.offsetTop - this.$refs.detailnavbar.$el.offsetHeight);
          this.typeTopY.push(Number.MAX_VALUE);
          console.log('topYarr',this.typeTopY);
        }, 100);
        
    },
    components:{
        DetailNavBar,
        DetailSwiper,
        DetailBasicInfo,
        Scroll,
        DetailShopInfo,
        DetailImagesInfo,
        DetailParamsInfo,
        DetailComment,
        GoodsList,
        DetailBottomBar,
        BackTop
    },
    mounted(){
      /* 
        这里面的代码和home.vue中事件总线的的代码一摸一样，我们可以用mixin混入的方法省去这些重复的代码
      */
      //detail组件中也有goodsList组件，里面的图片同样也需要监听是否加载完成并加入防抖函数
     //接收防抖函数返回的函数(这个函数中的第二个参数可以省略，因为时间间隔即使是0，setTimeout函数也会延迟执行)
      const refresh = debounce(this.$refs.scroll.scrollRefresh, 100);
      //为data中声明的图片相关的参数进行赋值
      this.itemImgListener = () => {
          // console.log('recommend图片加载了');
        //这样会导致刷新次数太频繁，影响性能，考虑利用防抖函数解决
        // this.$refs.scroll.scrollRefresh();
        refresh();
      }
      this.$bus.$on('itemImageLoad', this.itemImgListener);
      
    },
    destroyed(){
      /* 
        同样也需要在离开的时候关闭事件总线中对图片加载的监听，但是detail组件不被keep-alive包裹，不像home组件那样
        在deactivated中关闭事件总线中对图片的监听，所以我们需要写在destory声明周期中。
      */
      // this.$bus.$off('itemImageLoad', this.recommendImgListener);
    }
}
</script>
<style lang="css">
    .detail{
      height: 100vh;
      background: #ffffff;
      position: relative;
      z-index: 1;
    }
    .detail .content2 {
      background: #ffffff;
      height: calc(100% - 44px - 50px);/* 滑动区域必须给他指定高度 */
    }
</style>